﻿' LibWowArmory
' by Ronald M. Clifford (roncli@roncli.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports roncliProductions.LibWowArmory
Imports roncliProductions.LibWowArmory.TalentTree
Imports System
Imports System.Collections.ObjectModel
Imports System.Globalization
Imports System.IO
Imports System.Linq
Imports System.Xml.Serialization
Imports System.Web

Namespace roncliProductions.LibWowArmory.Character.Talents

    ''' <summary>
    ''' A class that retrieves a character's talents from the Armory
    ''' </summary>
    ''' <remarks></remarks>
    Public Class CharacterTalents
        Inherits WowArmoryData

        Private ctPage As New Schema.page
        Private tPrimary As TalentTree.TalentTree
        Private tSecondary As TalentTree.TalentTree
        Private pPets As New Collection(Of Pet)
        Private gPrimary As New Collection(Of Glyph)
        Private gSecondary As New Collection(Of Glyph)

        ''' <summary>
        ''' The realm the character is on
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Realm As String

        ''' <summary>
        ''' The name of the character
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Name As String

        ''' <summary>
        ''' The URL that will be used to retrieve the character's talents from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property URL As String
            Get
                Return String.Format(CultureInfo.InvariantCulture, "http://www.wowarmory.com/character-talents.xml?r={0}&n={1}", Realm, Name)
            End Get
        End Property

        ''' <summary>
        ''' Indicates to the inherited class that this request does not require login
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property RequiresLogin As Boolean
            Get
                Return False
            End Get
        End Property

        ''' <summary>
        ''' The character's primary talents
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property PrimaryTalents As TalentTree.TalentTree
            Get
                Return tPrimary
            End Get
        End Property

        ''' <summary>
        ''' The character's secondary talents
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property SecondaryTalents As TalentTree.TalentTree
            Get
                Return tSecondary
            End Get
        End Property

        ''' <summary>
        ''' The character's pets
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Pets As Collection(Of Pet)
            Get
                Return pPets
            End Get
        End Property

        ''' <summary>
        ''' The character's glyphs for their primary talents
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property PrimaryGlyphs As Collection(Of Glyph)
            Get
                Return gPrimary
            End Get
        End Property

        ''' <summary>
        ''' The character's glyphs for their secondary talents
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property SecondaryGlyphs As Collection(Of Glyph)
            Get
                Return gSecondary
            End Get
        End Property

        ''' <summary>
        ''' The date this character was last modified on the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property LastModified As Date
            Get
                Return CDate(ctPage.characterInfo.First.character.First.lastModified)
            End Get
        End Property

        ''' <summary>
        ''' A constructor to load a character's talents by realm and character name
        ''' </summary>
        ''' <param name="strRealm"></param>
        ''' <param name="strName"></param>
        ''' <remarks></remarks>
        Public Sub New(ByVal strRealm As String, ByVal strName As String)
            Me.Realm = strRealm
            Me.Name = strName
            Load()
        End Sub

        ''' <summary>
        ''' Loads the character's talents from the Armory
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            Dim strKey As String = String.Format(CultureInfo.InvariantCulture, "LibWowArmory.CharacterTalents.{0}.{1}", Realm, Name)
            If Cache.Cache(strKey) Is Nothing Then
                MyBase.Retrieve()

                Dim xsSerializer As New XmlSerializer(ctPage.GetType)

                Using srXML As New StringReader(MyBase.Data)
                    ctPage = CType(xsSerializer.Deserialize(srXML), Schema.page)
                End Using

                Cache.Cache.Insert(strKey, ctPage, Nothing, Date.UtcNow.AddDays(1), Nothing, Caching.CacheItemPriority.Normal, Nothing)
            Else
                ctPage = CType(Cache.Cache(strKey), Schema.page)
            End If

            If ctPage Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve talents for does not exist.")
            End If
            If ctPage.characterInfo Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve talents for does not exist.")
            End If
            If ctPage.characterInfo.First.character Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve talents for does not exist.")
            End If
            If ctPage.characterInfo.First.character.First Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve talents for does not exist.")
            End If
            If ctPage.characterInfo.First.talents Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve talents for does not exist.")
            End If

            Dim strTalents As String

            tPrimary = New TalentTree.TalentTree(CType(ctPage.characterInfo.First.character.First.classId, Enums.ClassType))
            strTalents = ctPage.characterInfo.First.talents.First.talentGroup.Where(Function(tg) tg.group = 1).First.talentSpec.First.value
            For intCount As Integer = 0 To strTalents.Length - 1
                If Not (tPrimary.GetTalentByID(intCount) Is Nothing) Then
                    tPrimary.GetTalentByID(intCount).Points = CInt(strTalents.Chars(intCount).ToString)
                End If
            Next
            gPrimary = (From g In ctPage.characterInfo.First.talents.First.talentGroup.Where(Function(tg) tg.group = 1).First.glyphs.First.glyph Select New Glyph(g.effect, g.icon, g.id, g.name, g.type)).ToCollection

            If ctPage.characterInfo.First.talents.First.talentGroup.Count = 2 Then
                tSecondary = New TalentTree.TalentTree(CType(ctPage.characterInfo.First.character.First.classId, Enums.ClassType))
                strTalents = ctPage.characterInfo.First.talents.First.talentGroup.Where(Function(tg) tg.group = 2).First.talentSpec.First.value
                For intcount As Integer = 0 To strTalents.Length - 1
                    If Not (tSecondary.GetTalentByID(intcount) Is Nothing) Then
                        tSecondary.GetTalentByID(intcount).Points = CInt(strTalents.Chars(intcount).ToString)
                    End If
                Next
                gSecondary = (From g In ctPage.characterInfo.First.talents.First.talentGroup.Where(Function(tg) tg.group = 2).First.glyphs.First.glyph Select New Glyph(g.effect, g.icon, g.id, g.name, g.type)).ToCollection
            Else
                tSecondary = Nothing
                gSecondary = Nothing
            End If

            If ctPage.characterInfo.First.talents.First.pet Is Nothing Then
                pPets = Nothing
            Else
                Dim strTalentTree As String
                Dim tPet As Tree
                For Each pSchemaPet As Schema.pet In ctPage.characterInfo.First.talents.First.pet
                    strTalentTree = pSchemaPet.talentGroup.First.prim
                    tPet = New TalentTree.TalentTree(Enums.ClassType.Unknown).TalentTrees.Where(Function(tt) tt.Name = strTalentTree).First
                    strTalents = pSchemaPet.talentGroup.First.talentSpec.First.value
                    For intCount As Integer = 0 To strTalents.Length - 1
                        If tPet.Talents.Count > intCount Then
                            tPet.Talents(intCount).Points = CInt(strTalents.Chars(intCount).ToString)
                        End If
                    Next
                    pPets.Add(New Pet(pSchemaPet.family, pSchemaPet.icon, pSchemaPet.level, pSchemaPet.name, pSchemaPet.npcId, pSchemaPet.npcName, pSchemaPet.talentGroup.First.prim, tPet))
                Next
            End If
        End Sub

    End Class

End Namespace